/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 *
 */

import { expect } from '@jest/globals';
import { readdirSync } from 'fs-extra';
import { resolve } from 'path';

import { initByFAEmptyApp, initByStageEmptyApp, initExecuteCommand, runHvigor } from './common/common';
import { ModuleBuildProfileModifier } from './common/modifier/module-build-profile-modifier';
import { Probes } from './common/probes';

/**
 * feature关联多entry场景测试
 */
describe('Features relate to multi Entries test', () => {
  // 测试feature关联多entry deviceType交集校验
  test.concurrent('Features relate to multi Entries for STAGE', async () => {
    await initByStageEmptyApp({
      cb: async (dir) => {
        testForCheckIntersection(dir);
      }
    });
  });

  test.concurrent('Features relate to multi Entries for FA', async () => {
    await initByFAEmptyApp({
      cb: async (dir) => {
        testForCheckIntersection(dir);
      }
    });
  });

  // 测试output_metadata.json文件是否正常生成
  test.concurrent('Generate OutputMetadata for STAGE', async () => {
    await initByStageEmptyApp({
      cb: async (dir) => {
        testForOutputMetadata(dir, true);
      }
    });
  });

  test.concurrent('Generate OutputMetadata for FA', async () => {
    await initByStageEmptyApp({
      cb: async (dir) => {
        testForOutputMetadata(dir, false);
      }
    });
  });
});

/**
 * feature关联多entry deviceType交集校验
 * @param dir dir
 */
export function testForCheckIntersection(dir: string) {
  const entryBuildProfileModifier = new ModuleBuildProfileModifier(dir, 'entry');
  entryBuildProfileModifier.addTarget({
    name: 'target1',
    config: {
      deviceType: ['phone']
    }
  });

  const featureBuildProfileModifier = new ModuleBuildProfileModifier(dir, 'feature');
  featureBuildProfileModifier.addTarget({
    name: 'target1',
    config: {
      deviceType: ['tablet']
    }
  });

  const commands = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHap'
  });

  // 1.feature->target1与entry->target1设备类型不存在交集 校验报错
  const result1 = runHvigor(dir, commands);
  expect(result1.stderr.includes('don\'t overlap'));

  featureBuildProfileModifier.updateTarget({
    name: 'target1',
    config: {
      deviceType: ['phone']
    }
  });

  // 2.feature->target1与entry->target1设备类型存在交集 构建成功
  const result2 = runHvigor(dir, commands);
  expect(result2.stdout.includes('BUILD SUCCESSFUL'));

  // 3.feature关联entry,entry1.feature->target2与entry1->default进行交集校验,设备类型存在交集,校验ok
  featureBuildProfileModifier.setEntryModules(['entry', 'entry1']);
  featureBuildProfileModifier.addTarget({
    name: 'target2',
    config: {
      deviceType: ['wearable']
    }
  });
  const result3 = runHvigor(dir, commands);
  expect(result3.stdout.includes('BUILD SUCCESSFUL'));

  // 4.feature关联entry,entry1.feature->target2与entry1->default进行交集校验,设备类型不存在交集,校验失败
  featureBuildProfileModifier.updateTarget({
    name: 'target2',
    config: {
      deviceType: ['phone']
    }
  });
  const result4 = runHvigor(dir, commands);
  expect(result4.stderr.includes('don\'t overlap'));
}

/**
 * output_metadata.json文件生成测试
 *
 * @param dir dir
 * @param isStage 工程模型
 */
export function testForOutputMetadata(dir: string, isStage: boolean) {
  const commands = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHap'
  });

  const result = runHvigor(dir, commands);
  const taskName = isStage ? 'GenerateMetadata' : 'LegacyGenerateMetadata';
  expect(result.stdout.includes(`Finished :entry:default@${taskName}`));
  const probe = new Probes(dir, resolve(dir, 'entry'));
  const buildOutput = readdirSync(probe.getIntermediatesOutputMetadata());
  expect(buildOutput.sort()).toEqual([
    'output_metadata.json'
  ].sort());

  // 增量测试
  const incrementalResult = runHvigor(dir, commands);
  expect(incrementalResult.stdout.includes(`UP-TO-DATE :entry:default@${taskName}`));

  const featureBuildProfileModifier = new ModuleBuildProfileModifier(dir, 'entry');
  featureBuildProfileModifier.addTarget({
    name: 'target1',
    config: {
      deviceType: ['tablet']
    }
  });

  const incrementalResult1 = runHvigor(dir, commands);
  expect(incrementalResult1.stdout.includes(`Finished :entry:default@${taskName}`));
}
